﻿using Koala.Pro.Common;
using Koala.Pro.Common.Extension;
using Koala.Pro.Core.Models;
using Koala.Pro.Helpers;
using Koala.Pro.Services;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace Koala.Pro.Controls
{
    public partial class DeptControl : UserControl
    {
        private bool isInit;

        public static readonly DependencyProperty OuInfosProperty = DependencyProperty.Register("OuInfos", typeof(List<OuInfo>), typeof(DeptControl));

        public static readonly DependencyProperty SelectItemProperty = DependencyProperty.Register("SelectItem", typeof(OuInfo), typeof(DeptControl));

        public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(DeptControl), new FrameworkPropertyMetadata("所属机构", FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));

        public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(string), typeof(DeptControl), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnValuePropertyChanged));

        public static readonly DependencyProperty ValueChangedCommandProperty = DependencyProperty.Register("ValueChangedCommand", typeof(ICommand), typeof(DeptControl), new PropertyMetadata((object)null));

        public static readonly DependencyProperty CommandParameterProperty = DependencyProperty.Register("CommandParameter", typeof(object), typeof(DeptControl));

        public static readonly RoutedEvent ValueChangedEvent;

        public List<OuInfo> OuInfos
        {
            get
            {
                return (List<OuInfo>)GetValue(OuInfosProperty);
            }
            set
            {
                SetValue(OuInfosProperty, value);
            }
        }

        public OuInfo SelectItem
        {
            get
            {
                return (OuInfo)GetValue(SelectItemProperty);
            }
            set
            {
                SetValue(SelectItemProperty, value);
            }
        }

        public string Text
        {
            get
            {
                return (string)GetValue(TextProperty);
            }
            set
            {
                SetValue(TextProperty, value);
            }
        }

        public string? Value
        {
            get
            {
                return (string)GetValue(ValueProperty);
            }
            set
            {
                SetValue(ValueProperty, value);
            }
        }

        public ICommand ValueChangedCommand
        {
            get
            {
                return (ICommand)GetValue(ValueChangedCommandProperty);
            }
            set
            {
                SetValue(ValueChangedCommandProperty, value);
            }
        }

        public object CommandParameter
        {
            get
            {
                return GetValue(CommandParameterProperty);
            }
            set
            {
                SetValue(CommandParameterProperty, value);
            }
        }

        public event RoutedEventHandler ValueChanged
        {
            add
            {
                AddHandler(ValueChangedEvent, value);
            }
            remove
            {
                RemoveHandler(ValueChangedEvent, value);
            }
        }

        public DeptControl()
        {
            InitializeComponent();
        }

        protected override async void OnInitialized(EventArgs e)
        {
            base.OnInitialized(e);
            await Init();
        }

        public async Task Init()
        {
            if (!isInit && !this.IsInDesignMode())
            {
                List<OuInfo> list = await SecurityHelper.GetMyTopGroup(App.ViewModel.UserInfo);
                if (list.Count > 0)
                {
                    OuInfo parentInfo = list[0];
                    List<OuInfo> children = await BLLFactory<IOuService>.Instance.GetTreeByID(parentInfo.Id);
                    OuInfo ouNodeInfo = new OuInfo
                    {
                        Name = parentInfo.Name,
                        Id = parentInfo.Id
                    };
                    
                    ouNodeInfo.Children = children;
                    
                    OuInfos = new List<OuInfo>
                    {
                        new OuInfo
                        {
                            Name = "顶级目录",
                            Id = -1
                        },
                        ouNodeInfo
                    };
                }
                isInit = true;
            }
        }

        private static async void OnValuePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (!(d is DeptControl control) || control == null)
            {
                return;
            }
            string oldValue = e.OldValue?.ToString();
            string newValue = e.NewValue?.ToString();
            if (!newValue.IsNullOrEmpty())
            {
                if (!control.isInit)
                {
                    await control.Init();
                }
                List<OuInfo> list = control.OuInfos?.FindOuNodes((OuInfo s) => s.Id == newValue.ToInt32());
                if (list != null && list.Count > 0 && list[0] != null)
                {
                    control.SelectItem = list[0];
                }
                RoutedPropertyChangedEventArgs<string> routedPropertyChangedEventArgs = new RoutedPropertyChangedEventArgs<string>(oldValue, newValue, DeptControl.ValueChangedEvent);
                control.RaiseEvent(routedPropertyChangedEventArgs);
                control.ValueChangedCommand?.Execute(newValue);
            }
        }

        private void TreeComboBox_SelectedItemChanged(object sender, RoutedEventArgs e)
        {
            OuInfo selectItem = SelectItem;
            if (selectItem != null && Value != selectItem.Id.ToString())
            {
                Value = selectItem.Id.ToString();
            }
        }

        static DeptControl()
        {
            ValueChangedEvent = EventManager.RegisterRoutedEvent("ValueChangedEvent", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(DeptControl));
        }
    }
}
